package edu.thu.studio.ormdesigner.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;

import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamOmitField;

import edu.thu.studio.ormdesigner.util.Utils;

/**
 * 抽象模型，用于绘图
 *
 */
public abstract class AbstractModel implements Serializable, Cloneable {
    
    private static final long serialVersionUID = 4266969076408212298L;
    
    @XStreamOmitField()
    protected PropertyChangeSupport support;
    
    @XStreamOmitField()
    protected static boolean updateable = true;
    
    @XStreamAsAttribute()
    protected String id;
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public static void setUpdateable(boolean enabled) {
        updateable = enabled;
    }
    
    public static boolean isUpdateable() {
        return updateable;
    }
    
    public AbstractModel() {
        this.support = new PropertyChangeSupport(this);
    }
    
    protected void firePropertyChange(String name, Object oldValue, Object newValue) {
        this.support.firePropertyChange(name, oldValue, newValue);
    }
    
    protected void firePropertyChange(String name, int oldValue, int newValue) {
        this.support.firePropertyChange(name, oldValue, newValue);
    }
    
    protected void firePropertyChange(String name, boolean oldValue, boolean newValue) {
        this.support.firePropertyChange(name, oldValue, newValue);
    }
    
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        this.support.addPropertyChangeListener(listener);
    }
    
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        this.support.removePropertyChangeListener(listener);
    }
    
    public void refresh() {
        if (updateable) {
            this.firePropertyChange("refresh", null, null);
        }
    }
    
    public void refreshVisuals() {
        if (updateable) {
            this.firePropertyChange("refreshVisuals", null, null);
        }
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public AbstractModel clone() {
        AbstractModel clone = null;
        try {
            clone = (AbstractModel) super.clone();
            
            clone.support = new PropertyChangeSupport(clone);
            
        } catch (CloneNotSupportedException e) {
        }
        
        return clone;
    }
    
    public AbstractModel cloneAsNew() {
        AbstractModel clone = (AbstractModel) this.clone();
        clone.id = Utils.getUUID();
        return clone;
    }
    
    public boolean equals(Object model) {
        if (model instanceof AbstractModel) {
            if (null != id && id.trim().length() > 0) {
                return id.equals(((AbstractModel) model).id);
            }
        }
        return false;
    }
}
